/*
 * To change this license header, choose License Headers in Project Properties.
 * To change this template file, choose Tools | Templates
 * and open the template in the editor.
 */
package pt.iscte.iul.dcti.aa.agent;

import agente.Agente;
import ambiente.Accao;
import ambiente.Coordenada;
import ambiente.ElemAgente;
import java.util.Arrays;
import pt.iscte.iul.dcti.aa.algorithm.qlearning.QLearning;

/**
 *
 * @author Gedsimon Pereira
 * @author Simão Fernandes
 */
public class Agent extends Agente {

    private QLearning<Coordenada> mecAprend;
    private ElemAgente perProp;
    private Accao action;
    private Coordenada coordenada;
    //Somatoria da Recompensa+estadoseguinte+accao de transicao
    private final double alfa = 0.5;
    // percentagem de vezes que deve ser executada uma acção de exploração
    private final double epsilon = 0.1;
    private final double gama = 0.98;

    private static final int REC_MAX = 1;

    @Override
    public void agir() {

        if (perProp.isCarga()) {
            this.getAmb().reIniciar();
            action = null;
        }

        if (action != null) {
            this.getActuador().actuar(action);
        }
    }

    @Override
    public void iniciar() {
        coordenada = null;

        Accao[] accoes = Accao.gerarAccoes(Accao.Tipo.PEGAR);

        mecAprend = new QLearning<Coordenada>(Arrays.asList(accoes), alfa, gama, epsilon);
    }

    @Override
    public void percepcionar() {
        perProp = this.getSensorProprio().detectar();
    }

    @Override
    public void processar() {
        Coordenada cAtual = perProp.getPosicao();

        if (action != null) {
            double reforco = gerarReforco(coordenada, cAtual);
            mecAprend.assimilar(coordenada, action, cAtual, reforco);
        }
        coordenada = cAtual;
        action = mecAprend.seleccionarAccao(coordenada);

    }

    public double gerarReforco(Coordenada s, Coordenada sn) {

        if (perProp.isCarga()) {
            return REC_MAX;
        } else if (perProp.isColisao()) {
            return -REC_MAX;
        } else {
            return -s.dist(sn);
        }
    }

}
